import * as vscode from 'vscode'
import * as fs from 'fs'
import * as path from 'path'
import msgTml from '../tmpl/page.messages.tmpl'
import { parse } from '@babel/parser'
import generate from '@babel/generator'
import { JutroConfig } from '../types'

const prettier = require('prettier');

function getFileName(filePath: string) {
  const name = path.basename(filePath)
  const dotIdx = name.lastIndexOf('.')
  return name.slice(0, dotIdx)
}

async function updateMessageFile(code: string, filePath: string) {
  const options = prettier.resolveConfig(filePath)
  const formattedCode = await prettier.format(code, {
    ...options,
    filepath: filePath,
  })

  fs.writeFileSync(filePath, formattedCode)

  const fileDoc = await vscode.workspace.openTextDocument(filePath)
  vscode.window.showTextDocument(fileDoc)
}

function getUpdatedCode(oldCode: string, key: string, value: object) {
  const ast = parse(oldCode, {
    sourceType: 'module',
    plugins: ['jsx'],
  })

  const exportDefaultNode: any = ast.program.body.find(
    (node: any) => node.type === 'ExportDefaultDeclaration'
  )
  if (!exportDefaultNode) {
    return vscode.window.showErrorMessage('No export default found!')
  }

  const targetNode = exportDefaultNode.declaration.arguments[0]

  targetNode.properties.push({
    type: 'ObjectProperty',
    key: { type: 'Identifier', name: key },
    value: {
      type: 'StringLiteral',
      value: value,
    },
  })

  const newCode = generate(ast, {}, oldCode).code

  return newCode
}

export default function getExtractTextCmd(config: JutroConfig) {
  return vscode.commands.registerCommand('jutror.extractText', async () => {
    const editor = vscode.window.activeTextEditor
    if (!editor) {
      return vscode.window.showErrorMessage('No active text editor!')
    }
    const selectedText = editor.document.getText(editor.selection)
    if (!selectedText) {
      return vscode.window.showErrorMessage('No Text selected!')
    }

    const extractedTxtName = await vscode.window.showInputBox({
      prompt: 'Enter a name for the extracted text.',
    })

    if (!extractedTxtName) {
      return vscode.window.showErrorMessage('Invalid name!')
    }

    const currentFilePath = editor.document.uri.fsPath
    const currentFileName = getFileName(currentFilePath)
    const messageFilePath = path.join(
      path.dirname(currentFilePath),
      [...new Set(`${currentFileName}.messages.js`.split('.'))].join('.')
    )

    try {
			let oldCode = "";
			if (fs.existsSync(messageFilePath)) {
				oldCode = fs.readFileSync(messageFilePath, 'utf-8')
			} else {
				oldCode = msgTml(currentFileName, config.appPrefix || 'app');
			}

			const messageKey = extractedTxtName

			const messageValue = {
				id: `${
					config.appPrefix || 'app'
				}.${currentFileName}.${extractedTxtName}`,
				defaultMessage: `${selectedText}`,
			}

			const newCode = getUpdatedCode(oldCode, messageKey, messageValue)

			updateMessageFile(newCode, messageFilePath)

    } catch (error) {
      console.error('===>', error)
    }
  })
}
